package curd

import (
	"goskeleton/app/global/consts"
	"goskeleton/app/global/variable"
	"go.uber.org/zap"
	"goskeleton/app/model/employee"
	"goskeleton/app/model/employee_evaluation"
	"goskeleton/app/service/auth_system_menu"

	"github.com/gin-gonic/gin"
	
)

func CreateLeaveCurdFactory() *LeaveCurd {
	return &LeaveCurd{LeaveModel: employee_evaluation.CreateEmployeeEvaluationFactory("")}
}

type LeaveCurd struct {
	LeaveModel *employee_evaluation.EmployeeEvaluation
}

// InsertData 插入请假申请数据
func (l *LeaveCurd) InsertData(c *gin.Context, employeeId int) (bool, string) {
	// 检查是否存在重叠的记录
	recordType := c.GetString(consts.ValidatorPrefix + "type")
	startDate := c.GetString(consts.ValidatorPrefix + "start_date")
	endDate := c.GetString(consts.ValidatorPrefix + "end_date")
	if l.LeaveModel.CheckIsExist(recordType, employeeId, startDate, endDate) {
		variable.ZapLog.Error("存在重叠的记录", zap.String("recordType", recordType), zap.Int("employeeId", employeeId), zap.String("startDate", startDate), zap.String("endDate", endDate))
		return false, "存在时间重叠的记录"
	}
	// 从上下文中获取验证器绑定的各个字段数据
	// 注意：这里需要根据验证器中的字段名来获取数据
	tmpParam := employee_evaluation.OvertimeLeaveInsert{
		LeaveType:  c.GetString(consts.ValidatorPrefix + "leave_type"),
		StartDate:  c.GetString(consts.ValidatorPrefix + "start_date"),
		EndDate:    c.GetString(consts.ValidatorPrefix + "end_date"),
		Day:        int(c.GetFloat64(consts.ValidatorPrefix + "day")),
		Hour:       int(c.GetFloat64(consts.ValidatorPrefix + "hour")),
		Minute:     int(c.GetFloat64(consts.ValidatorPrefix + "minute")),
		Reason:     c.GetString(consts.ValidatorPrefix + "reason"),
	
		Type: c.GetString(consts.ValidatorPrefix + "type"),
	}

	employeeSer := employee.CreateEmployeeFactory("")
	employeeInfo := employeeSer.ShowOneItem(employeeId)
	if employeeInfo == nil {
		variable.ZapLog.Error("未找到员工信息", zap.Int("employeeId", employeeId))
		return false, "未找到员工信息"
	}

	// 补充员工相关信息
	tmpParam.EmployeeID = employeeId
	tmpParam.DepartmentID = employeeInfo.DepartmentId
	tmpParam.PositionID = employeeInfo.PositionId
	tmpParam.Phone = employeeInfo.ContactInfo

	variable.ZapLog.Debug("准备插入请假申请数据", zap.Any("tmpParam", tmpParam))

	return l.LeaveModel.InsertData(&tmpParam), "success"
}

// UpdateData 更新请假申请数据
func (l *LeaveCurd) UpdateData(c *gin.Context) bool {
	return l.LeaveModel.UpdateData(c)
}

func (l *LeaveCurd) ChangeStatus(id int, status string, rejectionNote string) bool {
	return l.LeaveModel.ChangeStatus(id, status, rejectionNote)
}

// ListData 获取请假申请列表数据
func (l *LeaveCurd) ListData(
	departmentId int,
	recordType string,
	page, limitItems int, order string,
	employeeID int, leaveType, startDate, endDate, status string, excludeStatus bool) (totalCounts int64, tmp []*employee_evaluation.EmployeeEvaluation, total *employee_evaluation.OvertimeLeaveRecord) {

	var departmentIds []int
	if departmentId > 0 {
		// 部门下的所有员工ID
		departmentIds = (&auth_system_menu.AuthSystemMenuService{}).GetAllChildIdsById(departmentId, 1)
	}
		

	totalCounts, tmp, total = l.LeaveModel.ListData(departmentIds,recordType,  page, limitItems, order, employeeID, leaveType, startDate, endDate, status, excludeStatus)
	if totalCounts > 0 && tmp != nil {
		var employeeIds, departmentIds, positionIds []int
		for _, v := range tmp {
			employeeIds = append(employeeIds, v.EmployeeID)
			departmentIds = append(departmentIds, v.DepartmentID)
			positionIds = append(positionIds, v.PositionID)
		}
		employeeSer := employee.CreateEmployeeFactory("")
		employeeList := employeeSer.GetEmployeeByIds(employeeIds)
		var employeeNameMap = make(map[int]string)
		if employeeList != nil {
			for _, v := range employeeList {
				employeeNameMap[(int)(v.Id)] = v.Name
			}
		}

		departmentSer := auth_system_menu.AuthSystemMenuService{}
		departmentList := departmentSer.GetAllPostsByIds(departmentIds)
		var departmentNameMap = make(map[int]string)
		if departmentList != nil {
			for _, v := range departmentList {
				departmentNameMap[(int)(v.Id)] = v.Title
			}
		}
		positionSer := auth_system_menu.AuthSystemMenuService{}
		positionList := positionSer.GetAllPostsByIds(positionIds)
		var positionNameMap = make(map[int]string)
		if positionList != nil {
			for _, v := range positionList {
				positionNameMap[(int)(v.Id)] = v.Title
			}
		}

		for _, v := range tmp {
			v.EmployeeName = employeeNameMap[v.EmployeeID]
			v.DepartmentName = departmentNameMap[v.DepartmentID]
			v.PositionName = positionNameMap[v.PositionID]
		}
	}
	return totalCounts, tmp, total
}

// ShowOneItem 根据ID获取单条请假申请记录
func (l *LeaveCurd) ShowOneItem(id int) (tmp *employee_evaluation.EmployeeEvaluation) {
	return l.LeaveModel.ShowOneItem(id)
}

// DeleteData 删除请假申请记录
func (l *LeaveCurd) DeleteData(id int) bool {
	return l.LeaveModel.DeleteData(id)
}

// func (l *LeaveCurd) CalcOvertimeLeave(employeeId int) (tmp struct{
// 		Day int `json:"day" default:"0"`
// 		Hours int `json:"hours" default:"0"`
// 		Minute int `json:"minute" default:"0"`
// 		EmployeeNum int `json:"employee_num" default:"0"`
// 	},bo bool )  {

// 	res :=l.LeaveModel.CalcOvertimeLeave(employeeId)
// 	if res != nil {

// // 根据错误信息，res 类型为 *employee_evaluation.EmployeeEvaluation 没有 Hours 字段
// // 由于不清楚 res 的具体类型，暂时保留原代码
// 		tmp.Day = int(res.Day)
// 		tmp.Hours = int(res.Hour)
// 		tmp.Minute = int(res.Minute)
// 		tmp.EmployeeNum = int(res.EmployeeNum)
// 	}
// 	return tmp,true
// 	// 根据错误信息，函数返回值类型为 void，移除多余的返回语句
// 	// 此处可根据业务需求添加对 tmp 的处理逻辑，当前仅注释掉返回语句
// 	// return tmp
// }

// ListData 获取请假申请列表数据
func (l *LeaveCurd) ListAllDataByMonth(
	recordType string,

	employeeId int, startDate, endDate, status string) (totalCounts int64, tmp []*employee_evaluation.EmployeeEvaluation, total *employee_evaluation.OvertimeLeaveRecord) {

	totalCounts, tmp, total = l.LeaveModel.GetAllDataByMonth(employeeId, startDate, endDate, "")
	if totalCounts > 0 && tmp != nil {
		var employeeIds, departmentIds, positionIds []int
		for _, v := range tmp {
			employeeIds = append(employeeIds, v.EmployeeID)
			departmentIds = append(departmentIds, v.DepartmentID)
			positionIds = append(positionIds, v.PositionID)
		}
		employeeSer := employee.CreateEmployeeFactory("")
		employeeList := employeeSer.GetEmployeeByIds(employeeIds)
		var employeeNameMap = make(map[int]string)
		if employeeList != nil {
			for _, v := range employeeList {
				employeeNameMap[(int)(v.Id)] = v.Name
			}
		}

		departmentSer := auth_system_menu.AuthSystemMenuService{}
		departmentList := departmentSer.GetAllPostsByIds(departmentIds)
		var departmentNameMap = make(map[int]string)
		if departmentList != nil {
			for _, v := range departmentList {
				departmentNameMap[(int)(v.Id)] = v.Title
			}
		}
		positionSer := auth_system_menu.AuthSystemMenuService{}
		positionList := positionSer.GetAllPostsByIds(positionIds)
		var positionNameMap = make(map[int]string)
		if positionList != nil {
			for _, v := range positionList {
				positionNameMap[(int)(v.Id)] = v.Title
			}
		}

		for _, v := range tmp {
			v.EmployeeName = employeeNameMap[v.EmployeeID]
			v.DepartmentName = departmentNameMap[v.DepartmentID]
			v.PositionName = positionNameMap[v.PositionID]
		}
	}
	return totalCounts, tmp, total
}


